package com.demon.net

import com.demon.logger.Logger
import io.reactivex.subscribers.ResourceSubscriber
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException

/**
 * 类简要描述
 * <p/>
 * <p>
 * 类详细描述
 * </p>
 *
 * @author zhaozeyang
 * @date 2020/8/25
 */
private const val TAG = "NetSubscriber"

abstract class DefaultNetSubscriber<T, R : IAppResponse<T>> : ResourceSubscriber<R>() {
  override fun onComplete() {
    onRequestFinished()
  }

  override fun onNext(t: R?) {
    when {
      // 请求响应成功
      t?.isSuccess() == true -> {
        onSuccess(t.getResponseData(), t.getResponseMessage())
      }
      // 请求session过期
      t?.isExpired() == true -> {
        onSessionExpired(t.getResponseMessage())
      }
      t?.isFailed() == true -> {
        onApiError(t.getResponseCode(), t.getResponseMessage())
      }
      // 请求失败
      else -> {
        onHttpError()
      }
    }
  }

  override fun onError(t: Throwable?) {
    when (t) {
      is HttpException -> {
        handleHttpException(t)
      }
      is ConnectException -> {
        handleConnectException(t)
      }
      is SocketTimeoutException -> {
        handleSocketTimeoutException(t)
      }
      is UnknownHostException -> {
        handleUnknownHostException(t)
      }
    }
  }

  private fun handleHttpException(exception: HttpException) {
    when (exception.response()?.code()) {
      NetConstant.HTTP_CODE_AUTHORIZED_ERROR -> {
        onSessionExpired(exception.response()?.message())
      }
      NetConstant.HTTP_CODE_FORBIDDEN -> {
        onHttpError()
      }

      NetConstant.HTTP_CODE_NOT_FOUND -> {
        onHttpError()
      }
      else -> {
        onHttpError()
      }
    }
  }

  private fun handleConnectException(exception: ConnectException) {
    Logger.e(TAG, "网络连接失败", exception)
    onHttpError()
  }

  private fun handleSocketTimeoutException(exception: SocketTimeoutException) {
    Logger.e(TAG, "网络连接失败", exception)
    onHttpError()
  }

  private fun handleUnknownHostException(exception: UnknownHostException) {
    Logger.e(TAG, "网络连接失败", exception)
    onHttpError()
  }

  /**
   * 调用成功
   */
  abstract fun onSuccess(
    t: T?,
    message: String?
  )

  /**
   * 调用失败
   */
  abstract fun onApiError(
    code: Int,
    message: String?
  )

  /**
   * 网络请求失败
   */
  abstract fun onHttpError()

  /**
   * Session过期
   */
  abstract fun onSessionExpired(message: String?)

  open fun onRequestFinished() {

  }

}